﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FinanSoft.Entities;
using FinanSoft.Utilities;
using FinanSoft.DataLayer;

namespace FinanSoft.BusinessLayer
{
    public class UserManager
    {
        #region Fields
        private bool _isError;
        private String _errorMessage;
        private bool _definiteError;
        private User _currentUser;
        private static UserManager _instance;
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor privado de la clase para permitir la implementacion del patron singleton
        /// </summary>
        private UserManager()
        {

        }
        #endregion

        #region Methods
        /// <summary>
        /// Metodo que obtienen la instancia existente de la clase. Si esta aun no ha sido instanciada, la instancia.
        /// </summary>
        public static UserManager GetInstance()
        {
            if (_instance == null)
                _instance = new UserManager();
            return _instance;
        }

        /// <summary>
        /// Retorna el usuario actual del sistema
        /// </summary>
        /// <returns> Objeto usuario con la informacion del usuario actual del sistema</returns>
        public User GetCurrentUser()
        {
            return this._currentUser;
        }
        #endregion

        #region Propiedades
        public bool IsError
        {
            get { return _isError; }
        }

        public String ErrorMessage
        {
            get { return _errorMessage; }
        }
        #endregion

        #region Métodos públicos de clase
        /// <summary>
        /// Método que se encarga de autenticar el logueo de un usuario al sistema
        /// </summary>
        /// <param name="username">Nombre usuario</param>
        /// <param name="password">Contraseña</param>
        /// <returns>Retorna un código de validación por si hubo éxito o no</returns>
        public Constants.ValidationCode LoginUser(String username, String password)
        {
            UserDataManager manager = UserDataManager.GetInstance();
            User loggedUser = manager.LoginUser(username, password);
            Constants.ValidationCode code = loggedUser.Autentication;
            if (code.Equals(Constants.ValidationCode.ConnectionFailed))
            {
                _isError = true;
                _errorMessage = Constants.ERROR_DB_CONNECTION;
            }
            else if (code.Equals(Constants.ValidationCode.LoginFailed))
            {
                _isError = true;
                _errorMessage = Constants.ERROR_LOGIN_FAILED;
            }
            else
            {
                _currentUser = loggedUser;
                _currentUser.Compañia = ReportDataManager.GetInstance().GetCompanyInfo();
            }
            return code;
        }

        /// <summary>
        /// Método que se encarga de autenticar el logueo de un vendedor al sistema
        /// </summary>
        /// <param name="username">Nombre vendedor</param>
        /// <param name="password">Contraseña</param>
        /// <returns>Retorna un código de validación por si hubo éxito o no</returns>
        public bool LoginSalesman(String username, String password)
        {
            UserDataManager manager = UserDataManager.GetInstance();
            User loggedUser = manager.LoginUser(username, password);
            Constants.ValidationCode code = loggedUser.Autentication;
            if (code.Equals(Constants.ValidationCode.ConnectionFailed))
            {
                _isError = true;
                _errorMessage = Constants.ERROR_DB_CONNECTION;
                return false;
            }
            else if (code.Equals(Constants.ValidationCode.LoginFailed))
            {
                _isError = true;
                _errorMessage = Constants.ERROR_LOGIN_FAILED;
                return false;
            }
            _currentUser = loggedUser;
            return true;
        }

        /// <summary>
        /// Método que se encarga de loguear a un usuario tipo cliente
        /// </summary>
        /// <param name="username">Nombre del usuario del cliente</param>
        /// <param name="password">Contraseña del cliente</param>
        /// <returns>La cuenta auxiliar asociada al cliente que se acaba de loguear, si falla retorna null</returns>
        public AuxiliarAccount LoginUserClient(String username, String password)
        {
            UserDataManager manager = UserDataManager.GetInstance();
            User loggedUser = manager.LoginUser(username, password);
            Constants.ValidationCode code = loggedUser.Autentication;
            if (code == Constants.ValidationCode.LoginSucceeded)
            {
                // Consigo el id de la cuenta auxiliar del usuario del clinte y busco la cuenta en memoria y la devuelvo
                int idAuxuliarAccount = UserDataManager.GetInstance().GetUserClienAuxtAccountId(loggedUser.Id);
                if (idAuxuliarAccount == Constants.INVALID_ID)
                    return null;
                _currentUser = loggedUser;
                return AuxiliaryAccountManager.GetInstance().GetAuxiliarAccount(idAuxuliarAccount);
            }
            else
            {
                return null;
            }
        }
        #endregion
    }
}
